import axiosInstance from '@utils/axiosInstance.ts'
import ResponseResult from "@models/ReturnResult.ts";
import {Resources} from '@models/Resources.ts'
import {globalConst} from "@constants/globalConst.ts"
import {Users} from "@models/User.js";
import {userJurisdictionLevel} from "@constants/userJurisdiction.ts";
import type {AxiosResponse} from "axios";
import {isNull} from "@utils/stringUtil.ts";
import Cookie from "js-cookie"
//全局资源
const STORAGE_KEY = 'GlobalResourcesData'
//用户资源
const STORAGE_USER_KEY = 'GlobalResourcesUserData'
//用户收藏
const USER_COLLECTION_KEY = 'UserCollectionList'

interface ResourceList {
    resources: Resources
    updateData: Date
    IsAllMsg: boolean
}

interface ResourceState {
    GlobalResourcesList: Array<ResourceList | null>
    allResourcesNum: number
}

const defaultState: ResourceState = {
    GlobalResourcesList: [],
    allResourcesNum: 0
}

function saveState(state: ResourceState) {
    localStorage.setItem(STORAGE_KEY, JSON.stringify(state))
}

function loadState(): ResourceState {
    const data = localStorage.getItem(STORAGE_KEY)
    if (!data) {
        console.warn('localStorage 中未发现任何资源数据，使用默认值。')
        return {...defaultState}
    }
    try {
        const parsed = JSON.parse(data)

        // 结构验证
        if (!Array.isArray(parsed.GlobalResourcesList) || typeof parsed.allResourcesNum !== 'number') {
            console.warn('localStorage 中资源数据结构异常，使用默认值。')
            return {...defaultState}
        }

        // Date反序列化（仅在你用到 updateData 时才需要）
        parsed.GlobalResourcesList = parsed.GlobalResourcesList.map((item: ResourceList | null) => {
            if (item) {
                return {
                    ...item,
                    updateData: new Date(item.updateData)
                }
            }
            return null
        })

        return parsed as ResourceState
    } catch (e) {
        console.warn('localStorage 中资源数据解析失败，使用默认值。')
        return {...defaultState}
    }
}

export function getResourcesSize() {
    return loadState().allResourcesNum
}

export async function getResources(rId: number): Promise<Resources | null> {
    const state = loadState()
    let index = -1

    // 尝试命中缓存
    if (state.GlobalResourcesList && state.GlobalResourcesList.length > 0) {
        index = state.GlobalResourcesList.findIndex(item =>
            item?.resources.rId === rId
        )

        const cachedItem = state.GlobalResourcesList[index]

        if (cachedItem && cachedItem.IsAllMsg && cachedItem.updateData && Date.now() - cachedItem.updateData.getTime() < 1000 * 60 * 60 * 12) {
            return cachedItem.resources
        }
    }
    // 没有命中，直接请求并更新缓存
    const res = await axiosInstance.get(`${globalConst.baseUrl}index/getResources/${rId}`)
    const result = ResponseResult.fromApiResponse(res.data)
    if (result.isSuccess()) {
        if (result.returnResult == null) {
            alert('您请求的资源不存在, 换一个试试')
            return null
        }
        const resource = Resources.fromApiResponse(result.returnResult)
        const newItem: ResourceList = {
            resources: resource,
            updateData: new Date(),
            IsAllMsg: true
        }
        if (index !== -1) {
            state.GlobalResourcesList[index] = newItem
        } else {
            state.GlobalResourcesList.push(newItem)
        }
        saveState(state)
        return resource
    } else {
        console.warn('获取资源失败:', result.msg)
        return null
    }
}

export async function getGlobalResourcesList(startIndex: number | null, endIndex: number | null): Promise<Resources[]> {
    let state = loadState()

    if (startIndex == null || startIndex < 0) startIndex = 0
    if (endIndex == null || endIndex <= 0) endIndex = 4
    if (startIndex > endIndex) [startIndex, endIndex] = [endIndex, startIndex]

    const returnResources: Resources[] = []
    let hasAllData = true

    if (endIndex >= state.allResourcesNum && state.allResourcesNum > 0) {
        endIndex = state.allResourcesNum
    }

    for (let i = startIndex; i <= endIndex; i++) {
        const item = state.GlobalResourcesList[i]
        if (!item || (item.updateData && Date.now() - item.updateData.getTime() > 1000 * 60 * 60 * 12)) {
            hasAllData = false
            break
        }
        returnResources.push(item.resources)
    }

    if (hasAllData) return returnResources

    try {
        axiosInstance.defaults.withCredentials = true
        const response = await axiosInstance.get(`${globalConst.baseUrl}index/getResources/${startIndex}/${endIndex}`)
        const r = ResponseResult.fromApiResponse(response.data)

        if (r.isSuccess()) {
            state.allResourcesNum = r.all
            const list: Array<Resources> = r.returnResults as Resources[]
            const now = new Date()

            for (let i = startIndex; i <= endIndex && i < r.all && (i - startIndex) < list.length; i++) {
                const resource = list[i - startIndex]
                state.GlobalResourcesList[i] = {
                    resources: resource,
                    updateData: now,
                    IsAllMsg: false
                }
                returnResources[i - startIndex] = resource
            }

            // 重新计算实际有效资源数量
            let realCount = 0
            for (let i = 0; i < state.allResourcesNum; i++) {
                if (state.GlobalResourcesList[i] !== null) {
                    realCount++
                } else {
                    break
                }
            }
            state.allResourcesNum = realCount

            saveState(state)
        } else {
            console.error('资源列表拉取请求失败!请稍后再试')
        }
    } catch (err) {
        console.error('请求资源失败:', err)
        return []
    }
    return returnResources
}

export function getUser() {
    const tourist = Users.fromApiResponse({
        userId: -1,
        userName: "游客用户",
        coin: 0,
        userHeadPortraitUrl: null,
        jurisdiction: userJurisdictionLevel.TOURIST_JURISDICTION.level,
    })

    // 从 cookie 获取用户信息
    const cookieUserMsg = Users.fromApiResponse({
        userName: Cookie.get('114514UserName') || '游客',
        coin: parseInt(Cookie.get('114514UserCoin') || '0'),
        userHeadPortraitUrl: Cookie.get('114514UserHeadPortraitUrl') || null,
        userId: parseInt(Cookie.get('114514UserId') || '-1'),
        jurisdiction: parseInt(Cookie.get('114514UserJurisdiction') || '0')
    });

    if (cookieUserMsg.userId === -1) {//用户过期时,令牌应该也差不多到期了,估计也就几秒的事
        localStorage.removeItem(STORAGE_USER_KEY);
        localStorage.removeItem(globalConst.tokenName)
        localStorage.removeItem(USER_COLLECTION_KEY)
        return tourist;
    }

    // 读取 localStorage 中缓存的用户信息
    let localStorageUserMsg;
    try {
        localStorageUserMsg = Users.fromApiResponse(
            JSON.parse(localStorage.getItem(STORAGE_USER_KEY) || '{}')
        );
        if (localStorageUserMsg.coin !== cookieUserMsg.coin)
            localStorageUserMsg.coin = cookieUserMsg.coin
    } catch (e) {
        localStorageUserMsg = tourist
    }

    // 返回顺序：localStorage > cookie > tourist
    return localStorageUserMsg.hasUserMsg() ? localStorageUserMsg : cookieUserMsg;
}

export function setUserTokenByResponse(response: AxiosResponse): undefined | null | string {
    const token = response.headers[globalConst.tokenName.toLowerCase()] as string | undefined;
    const bodyToken = response.data?.[globalConst.tokenName] ?? null;
    const cookieToken = Cookie.get(globalConst.tokenName);
    const localStorageToken = localStorage.getItem(globalConst.tokenName);
    if (!isNull(token)) {
        localStorage.setItem(globalConst.tokenName, <string>token)
        return token;
    }
    if (!isNull(bodyToken)) {
        localStorage.setItem(globalConst.tokenName, <string>bodyToken)
        return bodyToken;
    }
    if (!isNull(cookieToken)) {
        localStorage.setItem(globalConst.tokenName, <string>cookieToken)
        return cookieToken;
    }
    if (!isNull(localStorageToken)) {
        localStorage.setItem(globalConst.tokenName, <string>localStorageToken)
        return localStorageToken;
    }
    return null;
}

export function getUserToken() {
    return localStorage.getItem(globalConst.tokenName)
}

export function setUser(user: Users) {
    localStorage.setItem(STORAGE_USER_KEY, JSON.stringify(user));
}

export async function addUserCollectionList(requestId: number) {
    const userCollectionList = await getUserCollectionList();
    userCollectionList.push(requestId);
    localStorage.setItem(USER_COLLECTION_KEY, JSON.stringify(userCollectionList))
}

export async function delUserCollection(requestId: number) {
    const userCollectionList = await getUserCollectionList();
    for (let i = 0; i < userCollectionList.length; i++) {
        if (userCollectionList[i] == i)
            userCollectionList.splice(i, 1)
        break
    }
    localStorage.setItem(USER_COLLECTION_KEY, JSON.stringify(userCollectionList))
}

export async function getUserCollectionList(): Promise<Array<number>> {
    const user = getUser()
    if (!user.hasUserMsg()) return []

    const item = localStorage.getItem(USER_COLLECTION_KEY)
    if (item) {
        try {
            const parsed = JSON.parse(item)
            const cacheTime = new Date(parsed.getTimeAt)
            const isValid = (
                parsed.userId === user.userId &&
                Array.isArray(parsed.collectionList) &&
                Date.now() - cacheTime.getTime() < 1000 * 60 * 60 * 12
            )
            if (isValid) {
                return parsed.collectionList
            }
        } catch (e) {
            console.warn('本地收藏列表解析失败:', e)
        }
    }
    // 异步从服务器获取
    try {
        const response = await axiosInstance.get(
            `${globalConst.baseUrl}user/getUserCollectionList/${user.userId}`,
            {
                headers: {
                    [globalConst.tokenName]: getUserToken()
                }
            }
        )

        const data = ResponseResult.fromApiResponse(response.data)
        if (data.isSuccess()) {
            const collectionList = data.returnResults as Array<number>
            const newCache = {
                userId: user.userId,
                collectionList,
                getTimeAt: new Date().toISOString()
            }
            localStorage.setItem(USER_COLLECTION_KEY, JSON.stringify(newCache))
            return collectionList
        } else {
            alert('获取收藏列表失败因为：' + data.msg)
            return []
        }
    } catch (err) {
        console.error('网络错误，无法获取收藏列表：', err)
        return []
    }
}

export function dleAllDate() {
    localStorage.removeItem(STORAGE_KEY)
    localStorage.removeItem(USER_COLLECTION_KEY)
    //仅保留JWT令牌
    window.location.reload();
}
